#ifndef BITS_HEADER
#define BITS_HEADER

// this header needs
#include <stdio.h>
#include <stdlib.h>
#include "../ARRAY.h"

// bit and byte array, to hold bits or bytes read (large enough)
// data will be stored in big endian mode as I read that way
#define BYTE_HOLDER_LENGTH 64
#define BIT_HOLDER_LENGTH (CHAR_BIT * BYTE_HOLDER_LENGTH)
byte BYTE_HOLDER[BYTE_HOLDER_LENGTH] = {0};
byte BIT_HOLDER[BIT_HOLDER_LENGTH] = {0};

// clear the above arrays
void clear_bit_holder(void);
void clear_byte_holder(void);

// print the above arrays
void print_bit_holder(void);
void print_byte_holder(void);

// enum with bit shifting modes
typedef enum
{
  BITSHIFT_RIGHT,
  BITSHIFT_LEFT,
} BITSHIFT_T;

// bit shift functions for arrays (depend on SYS_ENDIAN)
byte arr_bitshift(void * array, umax arr_size, umax var_size, BITSHIFT_T bitshift_type);
void arr_n_bitshift(void * array, umax arr_size, umax var_size, BITSHIFT_T type, umax shift_count);
byte arr_circ_bitshift(void * array, umax arr_size, umax var_size, BITSHIFT_T bitshift_type);
void arr_n_circ_bitshift(void * array, umax arr_size, umax var_size, BITSHIFT_T bitshift_type, umax shift_count);

// get bits from memory and store them in BIT_ARRAY
smax get_bits(umax bit_cnt, umax lpad_cnt, void * src);

// get bits from bytes in memory (but in a little more hardcore way)
smax get_byte_bits(umax byte_cnt, umax lshifts, umax bit_cnt, umax lpad_cnt, void * src, ENDIAN_T endian);

// write bits in memory (bits from BYTE_HOLDER)
bool write_bits(umax bit_holder_pos, umax left_bitshifts, umax right_bitshifts, void * dest, ENDIAN_T dest_endian);

#include "BITS.c"

#endif // BITS_HEADER
